package com.sfddata.musicpillow.user.service.impl;

import cn.jpush.api.JPushClient;
import cn.jpush.api.common.Week;
import cn.jpush.api.common.resp.APIConnectionException;
import cn.jpush.api.common.resp.APIRequestException;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.Notification;
import cn.jpush.api.schedule.ScheduleResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sfddata.musicpillow.user.entity.SleepImprovePlan;
import com.sfddata.musicpillow.user.entity.SleepImprovePlanVo;
import com.sfddata.musicpillow.user.entity.SleepImprovePlanWithMathType;
import com.sfddata.musicpillow.user.service.SleepImprovePlanService;
import com.sfddata.musicpillow.user.mapper.SleepImprovePlanMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.xml.crypto.Data;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
* @author jiangyingou
* @description 针对表【sleep_improve_plan】的数据库操作Service实现
* @createDate 2023-08-21 13:49:52
*/
@Service
public class SleepImprovePlanServiceImpl extends ServiceImpl<SleepImprovePlanMapper, SleepImprovePlan>
    implements SleepImprovePlanService{

    protected static final Logger LOG = LoggerFactory.getLogger(SleepImprovePlanServiceImpl.class);
    private static final String appKey ="f234d437f2330ec0c504325e";
    private static final String masterSecret = "db1520785a64015087dacbf6";

    private static final String sportAlert = "运动时间到！起身做做运动吧，最好能微微出汗，这样晚上入睡会更容易";
    private static final String footAlert = "热水泡脚可以帮助心情放松，舒缓疲倦，晚上会睡得更好哦";
    private static final String milkAlert = "快到睡眠时间啦，现在喝杯热牛奶可以更快产生睡意";
    private static final String readAlert = "捧起身边的一本书来读读吧，记得放首轻音乐，把灯光调柔和一点哦";
    private static final String thinkAlert = "闭上眼静静冥想一会儿吧，放空大脑，心身合一，也许睁眼时会是另一番心境";
    private static final String musicAlert = "有困意了没？没有也没关系，打开APP播放睡眠场景的音乐，保准你没一会儿就困啦";
    private static final String sleepAlert = "该睡觉啦，每天同一时间入睡睡眠质量会更好，记得使用零压入眠哦";

    @Override
    public String setPlan(SleepImprovePlanVo plan, String id) throws Exception {

        QueryWrapper<SleepImprovePlan> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("plan_type", plan.getType());
        queryWrapper.eq("user_id", id);
        SleepImprovePlan one = this.getOne(queryWrapper);

        if ( plan.getPlanRepeat() == null || plan.getPlanRepeat().size() == 0 ){
            plan.setIsOpen(0);
        }

        //  取消推送
        if ( plan.getIsOpen() == 0 ){
            // 已关闭状态添加新计划
            if ( one == null ){
                SleepImprovePlan newPlan = new SleepImprovePlan();
                newPlan.setPlanType(plan.getType());
                newPlan.setUserId(Integer.valueOf(id));
                newPlan.setPlanTime(plan.getPlanTime());
                newPlan.setPlanRepeat(plan.getPlanRepeat().toString());
                newPlan.setIsOpen(0);
                this.save(newPlan);
                return null;
            }

            one.setIsOpen(0);
            one.setPlanRepeat(plan.getPlanRepeat().toString());
            one.setPlanTime(plan.getPlanTime());
            one.setScheduleId("");
            this.update(one ,queryWrapper);

            if ( one.getScheduleId() == null || one.getScheduleId() =="" ){
                return null;
            }
            // 关闭已有计划
            deleteSchedule(one.getScheduleId());
            return null;
        }
        // 打开推送
        ArrayList<Integer> planRepeat = plan.getPlanRepeat();
        String planTime = plan.getPlanTime();
        String type = plan.getType();
        if (type.equals("sport")){
            return setSubPlan(planTime, planRepeat, sportAlert, id);
        }else if (plan.getType().equals("foot")) {
            return setSubPlan(planTime, planRepeat, footAlert, id);
        }else if (plan.getType().equals("milk")) {
            return setSubPlan(planTime, planRepeat, milkAlert, id);
        }else if (plan.getType().equals("read")) {
            return setSubPlan(planTime, planRepeat, readAlert, id);
        }else if (plan.getType().equals("think")) {
            return setSubPlan(planTime, planRepeat, thinkAlert, id);
        }else if (plan.getType().equals("music")) {
            return setSubPlan(planTime, planRepeat, musicAlert, id);
        }else {
            return setSubPlan(planTime, planRepeat, sleepAlert, id);
        }

    }

    private void deleteSchedule(String id) {
        String scheduleId = id;
        JPushClient jpushClient = new JPushClient(masterSecret, appKey);

        try {
            jpushClient.deleteSchedule(scheduleId);
        } catch (APIConnectionException e) {
            LOG.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            LOG.error("Error response from JPush server. Should review and fix it. ", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
        }
    }

    @Override
    public void savePlan(SleepImprovePlanVo plan, String id, String scheduleId) {

        String repeat = plan.getPlanRepeat().toString();
        String time = plan.getPlanTime();

        SleepImprovePlan sleepImprovePlan = new SleepImprovePlan();
        sleepImprovePlan.setPlanRepeat(repeat);
        sleepImprovePlan.setPlanTime(time);
        sleepImprovePlan.setScheduleId(scheduleId);
        sleepImprovePlan.setUserId(Integer.valueOf(id));
        sleepImprovePlan.setPlanType(plan.getType());
        sleepImprovePlan.setIsOpen(plan.getIsOpen());

        // this.saveOrUpdate(sleepImprovePlan);

        QueryWrapper<SleepImprovePlan> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", Integer.valueOf(id));
        queryWrapper.eq("plan_type", plan.getType());

        SleepImprovePlan one = this.getOne(queryWrapper);
        if(one == null){

            this.save(sleepImprovePlan);

        }else {
            // 删除老的
            if (!one.getScheduleId().equals("")){
                deleteSchedule(one.getScheduleId());
            }
            sleepImprovePlan.setId(one.getId());
            this.updateById(sleepImprovePlan);
        }

    }

    @Override
    public List<SleepImprovePlanWithMathType> getByUserid(String id) {

        QueryWrapper<SleepImprovePlan> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", id);
        List<SleepImprovePlan> list = this.list(queryWrapper);
        List<SleepImprovePlanWithMathType> typeList = new ArrayList<SleepImprovePlanWithMathType>();
        for (SleepImprovePlan plan : list) {

            SleepImprovePlanWithMathType type = new SleepImprovePlanWithMathType();
            BeanUtils.copyProperties(plan, type);
            if (type.getPlanType().equals("sport")){
                type.setType(1);
            }if (type.getPlanType().equals("foot")){
                type.setType(2);
            }if (type.getPlanType().equals("milk")){
                type.setType(3);
            }if (type.getPlanType().equals("read")){
                type.setType(4);
            }if (type.getPlanType().equals("think")){
                type.setType(5);
            }if (type.getPlanType().equals("music")){
                type.setType(6);
            }if (type.getPlanType().equals("sleep")){
                type.setType(7);
            }

            typeList.add(type);
        }


        return typeList;
    }

    public synchronized String setSubPlan(String time1, ArrayList<Integer> repeat, String Alert, String id) throws Exception {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Calendar now = Calendar.getInstance();
        String nowTime = format.format(now.getTime());
        now.add(Calendar.MONTH, 11);
        String oneYear = format.format(now.getTime());

        JPushClient jPushClient = new JPushClient(masterSecret, appKey);
        String name = "泛音FINE"+id;
        String start = nowTime;
        String end = oneYear;
        System.out.println(end+"soutend");
        String time = time1;
        Week[] days = convertEnum(repeat);
        // 用户
        PushPayload push = buildPushObject_all_alias_alert(Alert, id);
        ScheduleResult result = new ScheduleResult();
        try {
            result = jPushClient.createWeeklySchedule(name, start, end, time, days, push);
            LOG.info("schedule result is " + result);
        } catch (APIConnectionException e) {
            LOG.error("Connection error. Should retry later. ", e);

            throw new Exception(e.getMessage());
        } catch (APIRequestException e) {

            LOG.error("Error response from JPush server. Should review and fix it. ", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
            throw new Exception(e.getMessage());
        }

        return result.getSchedule_id();
    }


    public static PushPayload buildPushObject_all_alias_alert(String alert, String id) {
        return PushPayload.newBuilder()
                .setOptions(
                        Options.newBuilder()
                                .setApnsProduction(true).build()
                )
                .setPlatform(Platform.all())
                .setAudience(Audience.alias("qs"+id))
                .setNotification(Notification.alert(alert))
                .build();
    }

    public static Week[] convertEnum(ArrayList<Integer> repeat){
        ArrayList<Week> weeks = new ArrayList<>();
        for (Integer day : repeat) {
            switch (day) {
                case 1:
                    weeks.add(Week.MON);
                case 2:
                    weeks.add(Week.TUE);
                case 3:
                    weeks.add(Week.WED);
                case 4:
                    weeks.add(Week.THU);
                case 5:
                    weeks.add(Week.FRI);
                case 6:
                    weeks.add(Week.SAT);
                case 7:
                    weeks.add(Week.SUN);
            }
        }
        return weeks.toArray(new Week[weeks.size()]);
    }

}




